package com.streambolics.worseminton.data;

import java.util.ArrayList;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import com.streambolics.data.PersistentObject;

public abstract class WorsemintonObjectList<T extends PersistentObject> extends WorsemintonConstructedObject
{
    private PersistenceManager database;
    private List<T>            list;
    private ArrayList<T>       newList;

    /**
     * Appends an element to the list.
     * 
     * @param aElement
     *            The element to add.
     */

    public void append (T aElement)
    {
        if (newList == null)
        {
            newList = new ArrayList<T> (getElements ());
            list = newList;
        }
        newList.add (aElement);
    }

    /**
     * Redefine this function to bind variables in the query.
     * 
     * @param aQuery
     *            The query containing the variables to bind.
     */

    protected void bindQueryVariables (Query aQuery)
    {
    }

    /**
     * The query that returns the list of elements.
     * 
     * @return
     */

    protected abstract String buildQueryText ();

    protected void delayLoad (PersistenceManager aDatabase)
    {
        database = aDatabase;
    }

    protected Object executeQuery (Query aQuery)
    {
        return aQuery.execute ();
    }

    /**
     * Get the list of elements. The list is built the first time this function
     * is called.
     * 
     * @return The list of items.
     */

    @SuppressWarnings("unchecked")
    public List<T> getElements ()
    {
        if (list == null)
        {
            String qt = buildQueryText ();
            Query q = database.newQuery (qt);
            bindQueryVariables (q);
            list = (List<T>) executeQuery (q);
            for (T l : list)
            {
                l.setDatabase (database);
            }
        }
        return list;
    }

    /**
     * Utility function that returns a standard query.
     * 
     * @param aClass
     *            The class of the object list. Required because of type
     *            erasure.
     * @return The simplest select that selects all items in the database.
     */

    protected String standardQueryText (Class<T> aClass)
    {
        return "select from " + aClass.getName ();
    }
}